// 类型注解
// let a:number = 18

// a = 1

// console.log(a);

//原始类型

// let a:number = 1
// let b:string = '1'
// let c:undefined = undefined
// let d:null = null
// let e:boolean = false

//数组类型
// const arr:number[] = [1]
// const arrString:string[] = [1]

// const arr:Array<number> = [1,'1']

//联合类型
// const arr:(number | string)[] = [1,'1']
// const arr:Array<(number | string)> = [1,'1']

// let timer:number | null = null


// timer = setTimeout(() => {
    
// }, 1000);

// const arr:(number | string)[] = ['1']

// const arr: Array<number | string> = [1,'1']

// const arr:(number | string)[] = [1,'1']
// const arr1:(number | string)[] = [1,'1']
// const arr2:(number | string)[] = [1,'1']
// const arr3:(number | string)[] = [1,'1']

// 类型别名

// let const var 声明变量
// type 声明类型
// 遵循大驼峰语法
// type CustomArr = (number | string)[]

// const arr:CustomArr = [1,'1']
// const arr1:CustomArr = [1,'1']
// const arr2:CustomArr = [1,'1']
// const arr3:CustomArr = [1,'1']

// 函数类型

//分别指定 参数类型和返回值类型
// function fn(num1:number,num2:number): number {
//     return num1+num2
//     // return '1'
// }

// const fn2 = (num1:number,num2:number):number => num1+num2
// const fn2 = (num1:number):number => num1

// fn(1,2)

//同时指定需要用到类型别名，并且只支持函数表达式

// type AddFn = (num1:number,num2:number) => number


// const fn:AddFn = function (a,b) {
//     return 1
// }

// const fn2:AddFn = (c,d) => c+d 

// fn(1,2)

// fn2(2,3)

//没有返回值返回void不要返回undefined
// const fn = (num1:number):void => {
//     console.log(num1);
// }


// 可选参数使用？，一定放在必选参数后面
// const fn = (num1:number,num2?:number):void => {
//     console.log(num1);
//     console.log(num2);
// }


//对象类型
//空对象

// const obj:{} = {
//     name:1
// }

// obj.name = 1

// const obj:{name:string;age:number;sayHi(num1:number):number} = {
//     name:'harry',
//     age:18,
//     sayHi(num1) {
//         console.log('hi');
//         return num1
//     }
// }

// const obj:{
//     name:string
//     age:number
//     sayHi(num1:number):number
// } = {
//     name:'harry',
//     age:18,
//     sayHi(num1) {
//         console.log('hi');
//         return num1
//     }
// }

// obj.name = 'despot'
// obj.age = 123
// obj.sayHi(1)

// const obj:{
//     name:string
//     age?:number
//     sayHi:(num1:number) => number
// } = {
//     name:'harry',
//     sayHi(num1) {
//         console.log('hi');
//         return num1
//     }
// }

// type Config = {
//     url:string
//     method?:string
// }


// const axios =(config:{url:string;method?:string}):void => {}
// const axios =(config:Config):void => {}

// axios({url:'/hello.com'})

// type Student = {
//     name:string,
//     gender:string | number,
//     score:number,
//     study:() => void,
//     height?:number
//     play?:() => void
// }

// const student:Student = {
//     name:'harry',
//     gender:1,
//     score:60,
//     height:120,
//     study:() => {
//         console.log('好好学习，天天向上');
//     },
//     play:() => {
//         console.log('娱乐一下');
//     },
// }

//接口
// interface Person {
//     name:string
//     age:number
//     sayHi:() => void
// }

// const person:Person = {
//     name:'harry',
//     score:100,
//     age:29,
//     sayHi:() => {
//         console.log('hi');
//     }
// }


// interface Student {
//     name:string,
//     gender:string | number,
//     score:number,
//     study:() => void,
//     height?:number
//     play?:() => void
// }
// const student:Student = {
//     name:'harry',
//     gender:1,
//     score:60,
//     height:120,
//     study:() => {
//         console.log('好好学习，天天向上');
//     },
//     play:() => {
//         console.log('娱乐一下');
//     },
// }

// interface继承
// interface Point2D {
//     x: number;
//     y: number;
// }

// interface Point3D extends Point2D {
//     z: number;
// }

// const point:Point3D = {
//     x:1,
//     y:2,
//     z:3
// }


// type继承：交叉类型
// type Point2D = {
//     x: number;
//     y: number;
// }

// type Point3D = Point2D & {
//     z:number
// }

// const point:Point3D = {
//     x:1,
//     y:2,
//     z:3
// }


//类型推断
// let a = 18

// a = 1

// const add = (num1: number, num2: number) => {
//     return num1 + num2;
// };

//自定义类型
// let uname:'harry' = 'harry'

// uname = 'jack'

// let age:19 = 19

// age = 18

// let str1 = 'hello ts'

// const str2 = 'hello ts'

// type Gender = '男' | '女'

// let gender:Gender = '男'

// let a

// a = 1

// a = '1'

// a = false

// a = {}

// const aLink = document.getElementById('link')

// const aLink = document.getElementById('link')

// console.dir(aLink)


// 泛型别名
// type Data<T> = {
//     msg:string,
//     code:number,
//     data:T
// }
// type User = {
//     name:string,
//     age:number
// }


// type UserData = Data<User>

// type GoodsType = Data<number>

// const userData:UserData = {
//     msg:'chenggogn',
//     code:1,
//     data: {
//         name:'harry',
//         age:18
//     }
// } 

// const goods:GoodsType = {
//     msg:'chenggogn',
//     code:1,
//     data:18
// } 

// 泛型接口
// interface IdFn<T> {
//     id:() => T,
//     ids:() => T[]
// }

// const idObj:IdFn<number> = {
//     id() {
//         return 1
//     },
//     ids() {
//         return [1,2,3]
//     }
// }

// const arr = [1, 2, 3];

// arr.push(4)

// arr.forEach(item => console.log(item))


//泛型函数
function getId<T>(id:T):T {
    return id
}

let id1 = getId<number>(1)

let id2 = getId('1')